package alkaid.eis.schedule.domain;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.PrePersist;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Version;

import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import org.springframework.beans.BeanUtils;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import alkaid.eis.common.util.SnowflakeHelper;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

/**
 * 任务信息
 *  
 * @author Lucky Yang
 * @since 0.0.1
 */
@Setter
@Getter
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Entity
@Table(name = "eis_schedule_job_info")
@EntityListeners({AuditingEntityListener.class})
public class JobInfo {
    public static enum State {
        /** 停止 */
        STOPPED,
        /** 启动 */
        STARTED;
    }

    @Id
    @EqualsAndHashCode.Include
    @Column(updatable = false, nullable = false, unique = true)
    private Long id;

    @Version
    @Column(nullable = false)
    private Integer version;

    @CreatedBy
    @Column(updatable = false)
    private String createBy;

    @LastModifiedBy
    @Column
    private String updateBy;

    @CreationTimestamp
    @Column(updatable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;

    @UpdateTimestamp
    @Temporal(TemporalType.TIMESTAMP)
    private Date updateTime;
 
    /** bean名称 */
    private String className;
    
    /** 方法名称 */
    private String methodName;

    /** 方法参数 */
    private String methodParams;

    /** cron表达式 */
    private String cronExpression;

    /** 备注 */
    private String remark;

    /** 启用 */
    private Boolean enabled;

    /** 状态 */
    @Enumerated(EnumType.STRING)
    private State state;

    @OneToMany(mappedBy = "jobInfo", cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
    private List<JobLog> logs = new ArrayList<>();

    public JobInfo() {
    }

    public JobInfo(String className, String methodName, String methodParams, String cronExpression, String remark) {
        this.className = className;
        this.methodName = methodName;
        this.methodParams = methodParams;
        this.cronExpression = cronExpression;
        this.remark = remark;
        this.enabled = true;
        this.state = State.STOPPED;
    }

    @PrePersist
    public void preAction() {
        if (id == null) {
            id = SnowflakeHelper.INSTANCE.nextId();
        }
    }

    public void copy(JobInfo source) {
        BeanUtils.copyProperties(source, this, "id,logs");
    }

    @Override
    public String toString() {
        StringBuilder sb =  new StringBuilder("[JobInfo={id=")
        .append(getId())
        .append(",className=")
        .append(className)
        .append(",methodName=")
        .append(methodName)
        .append(",className=")
        .append(className)
        .append(",methodParams=")
        .append(methodParams)
        .append(",remark=")
        .append(remark)       
        .append("}]");
        
        return sb.toString();
    }

    
}
